﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace FreedomX2.Core.Transport.SocketProvider
{
    public class SocketThread
    {
        public delegate void DeleBlocksThread(SocketThread socketThread, BlocksThreadSingle BTSPack);
        public event DeleBlocksThread BlockReceive;
        public delegate void DeleThreadFinish(System.Net.Sockets.Socket socket, SocketThread socketThread);
        public static event DeleThreadFinish ThreadFinish;

        #region Create and Static
        private SocketThread() { }
        static List<SocketThread> _BlocksThreads = new List<SocketThread>();
        private int _ID;
        public int ID
        {
            get { return _ID; }
            private set { _ID = value; }
        }
        public static void ThreadDispose(int SerialID)
        {
            var v = SocketThread._BlocksThreads.Find(a => a._SerialID == SerialID);
            v.BlockReceive -= null;
            _BlocksThreads.Remove(v);
        }
        public System.Net.Sockets.Socket SessionSocket = null;
        public PType Type
        {
            get { return (PType)Enum.Parse(typeof(PType), ID.ToString()); }
            set
            {
                _ID = (int)value;
            }
        }
        private int _SerialID;
        public int SerialID
        {
            get { return _SerialID; }
            set { _SerialID = value; }
        }
        private List<BlocksThreadSingle> _list;
        public List<BlocksThreadSingle> Blocks
        {
            get { return _list; }
        }
        public static SocketThread CreateSocketThread(PType protocolType)
        {
            var reThread = new SocketThread() { Type = protocolType, SerialID = GetIdleID(_BlocksThreads), _list = new List<BlocksThreadSingle>() };
            _BlocksThreads.Add(reThread);
            return reThread;
        }
        #endregion

        public static void ReceiveBytes(System.Net.Sockets.Socket socket, byte[] bytes)
        {
            var v = SocketConvert.ConvertToBTS(bytes);

            var vthis = _BlocksThreads.Find(a => a._SerialID == v.SerialID);
            if (vthis == null)
            {
                vthis = SocketThread.CreateSocketThread(v.Type);
                vthis.SerialID = v.SerialID;
            }
            vthis.SessionSocket = socket;
            vthis._list.Add(v);
            if (vthis.BlockReceive != null)
            {
                vthis.BlockReceive.Invoke(vthis, v);
            }
            if (v.Size != ProtocolVar.DefaultPackageContentSize)
            {
                if (ThreadFinish != null)
                    ThreadFinish.Invoke(socket, vthis);
            }
        }

        /// <summary>
        /// 获得空闲ID
        /// </summary>
        /// <param name="main"></param>
        /// <returns></returns>
        public static int GetIdleID(List<SocketThread> main)
        {
            lock (main)
            {
                int i = 0;
                while (true)
                {
                    var v = main.Find(a =>
                    {
                        return a.SerialID == i;
                    });
                    if (v == null)
                        break;

                    i++;
                }
                return i;
            }
        }
    }
    public class ThreadContent : BlocksThreadSingle
    {
    }
    public class BlocksThreadSingle
    {
        private int _ID;

        public int ID
        {
            get { return _ID; }
            set { _ID = value; }
        }
        private int _SerialID;

        public int SerialID
        {
            get { return _SerialID; }
            set { _SerialID = value; }
        }
        private int _Size;

        public int Size
        {
            get { return _Size; }
            set { _Size = value; }
        }
        private int _Custom;

        public int Custom
        {
            get { return _Custom; }
            set { _Custom = value; }
        }

        public PType Type
        {
            get { return (PType)Enum.Parse(typeof(PType), ID.ToString()); }
            set
            {
                _ID = (int)value;
            }
        }
        private ArrayList _BytesList = new ArrayList();

        public ArrayList BytesList
        {
            get { return _BytesList; }
            set { _BytesList = value; }
        }
    }
}
